#include <Windows.h>
#include <WindowsX.h>

#include <conio.h>
#include <iostream>
#include <string>
#include <stdio.h>
#include <tchar.h>
#include <sstream>

#include "ATMOS.h"
#include "ATMOS_MasterServer.h"
#include "ATMOS_DatabaseConnectionInfo.h"
#include "ATMOS_GameServerInfo.h"
#include "ATMOS_GameClientInfo.h"
#include "ATMOS_LogManager.h"

#define BUFF_SIZE 256
#define READCHAR(arg) gets_s(arg, BUFF_SIZE); c=arg[0];

int _tmain(int argc, _TCHAR* argv[])
{
	AllocConsole();

	ATMOS::LogManager *logManager = 0;

	char c = 0;
	try
	{		
		logManager = 
			new ATMOS::LogManager( 
#ifdef _DEBUG
			"MasterServer.debug.log.txt"
#else
			"MasterServer.log.txt"
#endif
			);

		ATMOS::NetworkConnectionInfo info;
		info.serverIP = "127.0.0.1";
		info.serverPort = 6677;
		info.clientPort = 6688;
		info.connectionPassword = "test";
		info.maxConnections = 10000;
		info.occasionalPing = true;
		info.unreliableTimeout = 30000;
		info.shutdownTime = 200;
		info.saveToFile( "../config/master_server_config.txt" );

		ATMOS::NetworkManagerServer server;
		server.initialize( info );
		ATMOS_LOG("server initialized");

		ATMOS::DatabaseConnectionInfo databaseConnection;
		databaseConnection.loadFromFile( "../config/master_server_database_connection.txt" );

		ATMOS::MasterServer masterServer( &server, databaseConnection );
		ATMOS_LOG("master server initialized");
		
		std::cout	<< "(q) quit" << std::endl
					<< "(c) list connected clients" << std::endl
					<< "(s) list connected servers" << std::endl
					<< "(p) purge all connected clients and servers" << std::endl;

		while( true )
		{
			server.update();
		
			if( _kbhit() )
			{
				char c = _getch();
				if( c == 's' )
				{				
					std::cout << "WAITING SERVERS: " << masterServer.getNumWaitingServers() << std::endl;
					ATMOS::GameServerInfoList cil = masterServer.getWaitingServers( 0, 10 );
					for( ATMOS::GameServerInfoList::iterator iter = cil.begin();
						iter != cil.end();
						++iter )
					{
						std::cout << "name: " << (*iter).name << std::endl
								<< " GUID: " << (*iter).masterServerGUID << std::endl
								<< " port: " << (*iter).port << std::endl << std::endl;
					}
				}
				else if( c == 'c' )
				{
					std::cout << "WAITING CLIENTS: "
						<< masterServer.getNumWaitingClients() << std::endl;
					ATMOS::GameClientInfoList cil = masterServer.getWaitingClients( 0, 10 );
					for( ATMOS::GameClientInfoList::iterator iter = cil.begin();
						iter != cil.end();
						++iter )
					{
						std::cout << "name: " << (*iter).name << std::endl
								<< " GUID: " << (*iter).masterServerGUID << std::endl
								<< " port: " << (*iter).port << std::endl << std::endl;
					}
				}
				else if( c == 't' )
				{
					static int numChats = 0;
					std::stringstream ss;
					ss << numChats;

					std::cout << std::endl;
					std::cout << "SENDING SERVER CHAT" << std::endl;
					std::cout << "-----------------------------" << std::endl;
					ATMOS::GameServerInfoList cil = masterServer.getWaitingServers( 0, 10 );
					for( ATMOS::GameServerInfoList::iterator iter = cil.begin();
						iter != cil.end();
						++iter )
					{
						ATMOS::Packet p( ATMOS::API_DEBUG_2, "" );
						p.writeString( "server message #" + ss.str() );
						++numChats;

						std::cout << "sending chat to server: " << (*iter).name << std::endl;
						server.sendPacket( &p, (*iter).masterServerGUID );
					}
					std::cout << "-----------------------------" << std::endl;
				}
				else if( c == 'u' )
				{
					static int numChats = 0;
					std::stringstream ss;
					ss << numChats;
					
					std::cout << std::endl;
					std::cout << "SENDING CLIENT CHAT" << std::endl;
					std::cout << "-----------------------------" << std::endl;
					ATMOS::GameClientInfoList cil = masterServer.getWaitingClients( 0, 10 );
					for( ATMOS::GameClientInfoList::iterator iter = cil.begin();
						iter != cil.end();
						++iter )
					{
						ATMOS::Packet p( ATMOS::API_DEBUG_1, "" );
						std::cout << "sending chat to client: " << (*iter).name << std::endl;
						p.writeString( "client message #" + ss.str() );
						++numChats;

						server.sendPacket( &p, (*iter).masterServerGUID );
					}
					std::cout << "-----------------------------" << std::endl;
				}
				else if( c == 'p' )
				{
					masterServer.removeAllClients();
					masterServer.removeAllServers();
					std::cout << "client and server records purged" << std::endl;
				}
				else if( c == 'q' )
				{
					break;
				}
			}

			Sleep( 30 );
		}

		server.shutdown();
	}
	catch( std::runtime_error &error )
	{
		ATMOS_LOG("error: " << error.what());
		while(!_kbhit());
	}
	catch( ... )
	{
		ATMOS_LOG("unknown exception");
		while(!_kbhit());
	}

	delete logManager;

	return 0;
}
